/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2017-2019. All rights reserved.
 * Description: ffdemuxer common function
 * Author: HiMobileCam middleware develop team
 * Create: 2017-12-22
 */

#ifndef FFDEMUX_COMMON_H
#define FFDEMUX_COMMON_H

#include <pthread.h>

#include "libavformat/avformat.h"

#include "hi_type.h"

#include "hi_demuxer.h"

#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif /* End of #ifdef __cplusplus */

typedef enum {
    HI_FFDEMUX_FORMAT_MP4 = 0,
    HI_FFDEMUX_FORMAT_TS,
    HI_FFDEMUX_FORMAT_WAV,
    HI_FFDEMUX_FORMAT_M4A,
    HI_FFDEMUX_FORMAT_BUTT
} FfDemuxFormat;

/* define HI_NULL handle for codedex check */
#define HI_NULL_HANDLE            0
#define UNUSED_ATTR               __attribute__((unused))
/* 30720 = 30 * 1024 = 30k */
#define FFMPEG_FRAME_BUF_DATA_LEN 30720
#define FFMPEG_MS_US_UNIT 1000
#define AAC_SAMPLE_RATE_NUM  13

typedef struct {
    pthread_mutex_t demuxMutex;
    AVFormatContext *formatContext;
    AVPacket pkt;
    HI_CHAR filePath[PATH_MAX + 1];
    HI_S32 videoStreamNum;
    HI_S32 usedVideoStreamIndex;
    HI_S32 videoStreamIndex;
    HI_S32 audioStreamIndex;
    HI_S32 metaStreamIndex;

    AVStream *usedVideoStream;
    AVStream *videoStream;
    AVStream *audioStream;
    AVStream *metaStream;

    enum AVCodecID enUsedVidCodecId;
    enum AVCodecID vidCodecId;
    enum AVCodecID enAudCodecId;
    enum AVCodecID enMetaCodecId;

    AVBSFContext *h26XBsfCtx;
    int64_t lastReadPts;
    HI_U8 audioData[FFMPEG_FRAME_BUF_DATA_LEN];
    HI_BOOL hasAdts;
    HI_S64 fileSize;
    HI_BOOL playMetaVid;  // play meta video or not

    HI_U32 sampleRate;
    HI_U32 chnnum;
    HI_U32 width;
    HI_U32 height;

    FfDemuxFormat enFormat;
    HI_FORMAT_STREAM_RESOLUTION_S stSteamResolution[HI_DEMUXER_RESOLUTION_CNT];
} FfDemuxFormatMember;

#define LOG_AND_RETURN_IF_NULL(handle) do {                                                             \
        if ((handle) == HI_NULL) {                                                                      \
            FFDEMUX_PRINTF(MODULE_NAME_DEMUX, HI_FFDEMUX_LOG_LEVEL_ERR, "demux handle is not valid \n"); \
            return HI_ERR_DEMUXER_INVALID_HANDLE;                                                        \
        }                                                                                                \
    } while (0)

#define FFDEMUX_LOCK(mutex)                 \
    do {                                    \
        (void)pthread_mutex_lock(&(mutex)); \
    } while (0)

#define FFDEMUX_UNLOCK(mutex)                 \
    do {                                      \
        (void)pthread_mutex_unlock(&(mutex)); \
    } while (0)

#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif /* __cplusplus */

#endif /* FFDEMUX_COMMON_H */
